{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e803587f",
   "metadata": {},
   "outputs": [],
   "source": [
    "from google.colab import drive\n",
    "drive.mount(\"/gdrive\", force_remount=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e37fa74f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import numpy as np\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "from torch.utils.data import (DataLoader, RandomSampler, TensorDataset)\n",
    "\n",
    "class Weltried(nn.Module):\n",
    "\n",
    "  def __init__(self, config):\n",
    "    super(Weltried, self).__init__()\n",
    "\n",
    "    # 입력층 노드 수\n",
    "    self.inode = config[\"input_node\"]\n",
    "    # 은닉층 데이터 크기\n",
    "    self.hnode = config[\"hidden_node\"]\n",
    "    # 출력층 노드 수: 분류해야 하는 레이블 수\n",
    "    self.onode = config[\"output_node\"]\n",
    "\n",
    "    # 활성화 함수로 Sigmoid 사용\n",
    "    self.activation = nn.Sigmoid()\n",
    "\n",
    "    # 신경망 설계\n",
    "    self.linear1 = nn.Linear(self.inode, self.hnode, bias=True)\n",
    "    self.linear2 = nn.Linear(self.hnode, self.onode, bias=True)  \n",
    "\n",
    "  def forward(self, input_features):\n",
    "\n",
    "    output1 = self.linear1(input_features)\n",
    "    hypothesis1 = self.activation(output1)\n",
    "\n",
    "    output2 = self.linear2(hypothesis1)\n",
    "    hypothesis2 = self.activation(output2)\n",
    "\n",
    "    return hypothesis2\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4cee0339",
   "metadata": {},
   "source": [
    "<h2> Load Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b655e7c6",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (Temp/ipykernel_2176/2677024153.py, line 3)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"C:\\Users\\jinsung\\AppData\\Local\\Temp/ipykernel_2176/2677024153.py\"\u001b[1;36m, line \u001b[1;32m3\u001b[0m\n\u001b[1;33m    (train_X, train_y), (test_X, test_y) =\u001b[0m\n\u001b[1;37m                                           ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "# 데이터 읽기 함수\n",
    "def load_dataset():\n",
    "    (train_X, train_y), (test_X, test_y) = \n",
    "\n",
    "    #train_X = train_X.reshape(-1, 28*28)\n",
    "    #test_X  = test_X.reshape(-1, 28*28)\n",
    "\n",
    "    train_X = torch.tensor(train_X, dtype=torch.float)\n",
    "    train_y = torch.tensor(train_y, dtype=torch.int)\n",
    "    test_X = torch.tensor(test_X, dtype=torch.float)\n",
    "    test_y = torch.tensor(test_y, dtype=torch.int)\n",
    "\n",
    "    return (train_X, train_y), (test_X, test_y)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "783f04f8",
   "metadata": {},
   "source": [
    "<h2> Model test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a3c0cdb7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 모델 평가 결과 계산을 위해 텐서를 리스트로 변환하는 함수\n",
    "def tensor2list(input_tensor):\n",
    "    return input_tensor.cpu().detach().numpy().tolist()\n",
    "\n",
    "# 평가 수행 함수\n",
    "def do_test(model, test_dataloader):\n",
    "\n",
    "    # 평가 모드 셋팅\n",
    "    model.eval()\n",
    "\n",
    "    # Batch 별로 예측값과 정답을 저장할 리스트 초기화b\n",
    "    predicts, golds = [], []\n",
    "    with torch.no_grad():\n",
    "        for step, batch in enumerate(test_dataloader):\n",
    "            # .cuda()를 통해 메모리에 업로드\n",
    "            batch = tuple(t.cuda() for t in batch)\n",
    "\n",
    "            input_features, labels = batch\n",
    "            hypothesis = model(input_features)\n",
    "            logits = (hypothesis > 0.5).float()\n",
    "            x = tensor2list(logits)\n",
    "            y = tensor2list(labels)\n",
    "\n",
    "            # ont-hot 표현으로 변경\n",
    "            logits = torch.argmax(hypothesis,-1)\n",
    "\n",
    "            x = tensor2list(logits)\n",
    "            y = tensor2list(labels)\n",
    "\n",
    "            # 예측값과 정답을 리스트에 추가\n",
    "            predicts.extend(x)\n",
    "            golds.extend(y)\n",
    "    \n",
    "        print(\"PRED=\",predicts)\n",
    "        print(\"GOLD=\",golds)\n",
    "        print(\"Accuracy= {0:f}\\n\".format(accuracy_score(golds, predicts)))\n",
    "\n",
    "# 모델 평가 함수\n",
    "def test(config):\n",
    "\n",
    "    model = Weltried(config).cuda()\n",
    "\n",
    "    # 저장된 모델 가중치 로드\n",
    "    model.load_state_dict(torch.load(os.path.join(config[\"output_dir\"], config[\"model_name\"])))\n",
    "\n",
    "    # 데이터 load\n",
    "    (_, _), (features, labels) = load_dataset()\n",
    "\n",
    "    test_features = TensorDataset(features, labels)\n",
    "    test_dataloader = DataLoader(test_features, shuffle=True, batch_size=config[\"batch_size\"])\n",
    "\n",
    "    do_test(model, test_dataloader)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82dd0acc",
   "metadata": {},
   "source": [
    "<h2> Model train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7f4c719b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 모델 학습 함수\n",
    "def train(config):\n",
    "    \n",
    "    model = Weltried(config).cuda()\n",
    "    (input_features, labels), (_, _) = load_dataset()\n",
    "\n",
    "    # TensorDataset/DataLoader를 통해 배치(batch) 단위로 데이터를 나누고 셔플(shuffle)\n",
    "    train_features = TensorDataset(input_features, labels)\n",
    "    train_dataloader = DataLoader(train_features, shuffle=True, batch_size=config[\"batch_size\"])\n",
    "\n",
    "    loss_func = nn.CrossEntropyLoss()\n",
    "    optimizer = torch.optim.Adam(model.parameters(), lr = config[\"learn_rate\"])\n",
    "\n",
    "    for epoch in range(config[\"epoch\"]+1):\n",
    "\n",
    "        # 학습 모드 셋팅\n",
    "        model.train()\n",
    "\n",
    "        # epoch 마다 평균 비용을 저장하기 위한 리스트\n",
    "        costs = []\n",
    "\n",
    "        for (step, batch) in enumerate(train_dataloader):\n",
    "            \n",
    "            # batch = (input_features[step], labels[step])*batch_size\n",
    "            # .cuda()를 통해 메모리에 업로드\n",
    "            batch = tuple(t.cuda() for t in batch)\n",
    "\n",
    "            # 각 feature 저장\n",
    "            input_features, labels = batch\n",
    "\n",
    "            # 역전파 변화도 초기화\n",
    "            # .backward() 호출 시, 변화도 버퍼에 데이터가 계속 누적한 것을 초기화\n",
    "            optimizer.zero_grad()\n",
    "\n",
    "            hypothesis = model(input_features)\n",
    "\n",
    "            cost = loss_func(hypothesis, labels)\n",
    "\n",
    "            # 역전파 수행\n",
    "            cost.backward()\n",
    "            optimizer.step()\n",
    "\n",
    "            # 현재 batch의 스텝 별 loss 저장\n",
    "            costs.append(cost.data.item())\n",
    "\n",
    "        # 에폭마다 평균 비용 출력하고 모델을 저장\n",
    "        print(\"Average Loss= {0:f}\".format(np.mean(costs)))\n",
    "        torch.save(model.state_dict(), os.path.join(config[\"output_dir\"], \"epoch_{0:d}.pt\".format(epoch)))\n",
    "        do_test(model, train_dataloader)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "29e55675",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (Temp/ipykernel_2176/1595566699.py, line 12)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"C:\\Users\\jinsung\\AppData\\Local\\Temp/ipykernel_2176/1595566699.py\"\u001b[1;36m, line \u001b[1;32m12\u001b[0m\n\u001b[1;33m    \"hidden_node\":,\u001b[0m\n\u001b[1;37m                  ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "if(__name__==\"__main__\"):\n",
    "\n",
    "    root_dir = \"/gdrive/My Drive/colab/mlp/weltried\"\n",
    "    output_dir = os.path.join(root_dir, \"output\")\n",
    "    if not os.path.exists(output_dir):\n",
    "        os.makedirs(output_dir)\n",
    "\n",
    "    config = {\"mode\": \"train\",\n",
    "              \"model_name\":\"epoch_{0:d}.pt\".format(10),\n",
    "              \"output_dir\":output_dir,\n",
    "              \"input_node\": 6,\n",
    "              \"hidden_node\":,\n",
    "              \"output_node\":,\n",
    "              \"learn_rate\":,\n",
    "              \"batch_size\":,\n",
    "              \"epoch\":10,\n",
    "              }\n",
    "\n",
    "    if(config[\"mode\"] == \"train\"):\n",
    "        train(config)\n",
    "    else:\n",
    "        test(config)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b698506b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "60d96c04",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1f677701",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bea66820",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a926a7a7",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3bc60130",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9e179eed",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b45c35aa",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c840467",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8606033d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "669d5bd8",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fe32b9d1",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88d41f93",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "324faa95",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9ce1a598",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a7de3c8",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b50e420a",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "000c8155",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "04dce55b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "95ed3496",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5f1624d3",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58813ca6",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d38170ad",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f80fbee",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
